
#include "connector.h"
#include <QtNetwork>
#include "sslclient.h"
#include "connectorthread.h"
#include <Core/logger/logger.h>

namespace Opl
{
    namespace Helpers
    {

        using Opl::Core::EntityObject;

        class ConnectorPrivate
        {
            public:
                ConnectorPrivate():
                    status(Disconnected)
                {}
                ~ConnectorPrivate() {}
                ConnectionStatus status;
                ConnectorSetup setup;
        };


        Connector::Connector(EntityObject* parent) :
            EntityObject(parent), O_PRIVATE_CREATE(Connector)
        {
            O_D(Connector);
            ConnectorThread::instance();
        }

        Connector::~Connector()
        {
            O_PRIVATE_DELETE;
        }

        void Connector::Setup(const ConnectorSetup& setup)
        {
            O_D(Connector);
            LI.Info("Connector::Setup");
            d->setup = setup;
            connect(ConnectorThread::instance(), SIGNAL(connected()), this, SLOT(threadConnected()));
            connect(ConnectorThread::instance(), SIGNAL(disconnected()), this, SLOT(threadDisconnected()));
            connect(ConnectorThread::instance(), SIGNAL(error()), this, SLOT(threadError()));
            ConnectorThread::instance()->Setup(setup);
        }

        void Connector::Start()
        {
            O_D(Connector);
            LI.Info("Connector::Start");
            ConnectorThread::instance()->start();
        }

        void Connector::Stop(bool force/* = false*/)
        {
            O_D(Connector);
            LI.Info(QString("Connector::Stop(force=%1)").arg(force));

            if (ConnectorThread::instance()->isRunning())
            {
                LI.Trace("ConnectorThread::isRunning");

                if (force) {
                    ConnectorThread::instance()->terminate();

                } else {
                    ConnectorThread::instance()->stop();
                    ConnectorThread::instance()->wait();
                }
            }
        }

        void Connector::threadOutput(const QString& data)
        {
            emit output(data);
        }

        void Connector::threadConnected()
        {
            O_D(Connector);
            emit connected();
        }

        void Connector::threadError()
        {
            O_D(Connector);
            Stop();
            if (d->setup.reconnectTime > 0)
            {
                QTimer::singleShot(d->setup.reconnectTime * 1000, this, SLOT(Start()));
            }
            emit error();
        }

        void Connector::threadDisconnected()
        {
            O_D(Connector);
            emit disconnected();
        }

        void Connector::Send(const QString& data)
        {
            O_D(Connector);
            ConnectorThread::instance()->Send(data);
        }

    }
}
